home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / ConfigSystem / configmanager.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-28  |  23.0 KB  |  731 lines

  1. //--------------------------------------------------------------------------------------
  2. // File: ConfigManager.cpp
  3. //
  4. // Implementation of configuration system functions.
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //--------------------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #include <stdio.h>
  10. #include "ConfigDatabase.h"
  11. #include "ConfigManager.h"
  12. #include <ddraw.h>
  13. #include <dsetup.h>
  14.  
  15.  
  16. typedef struct
  17. {
  18.     const char* Property;
  19.     bool (CConfigManager::*Func)(const char*);
  20. } CONFIGTABLE;
  21.  
  22. CONFIGTABLE ConfigTable[]= {
  23.     { "ForceShader",                      &CConfigManager::InitForceShader                      },
  24.     { "DisableDriverManagement",          &CConfigManager::InitDisableDriverManagement          },
  25.     { "LinearTextureAddressing",          &CConfigManager::InitLinearTextureAddressing          },
  26.     { "MaximumResolution",                &CConfigManager::InitMaximumResolution                },
  27.     { "UseFixedFunction",                 &CConfigManager::InitUseFixedFunction                 },
  28.     { "UnsupportedCard",                  &CConfigManager::InitUnsupportedCard                  },
  29.     { "DisableRenderTargets",             &CConfigManager::InitDisableRenderTargets             },
  30.     { "DisableAlphaRenderTargets",        &CConfigManager::InitDisableAlphaRenderTargets        },
  31.     { "OldDriver",                        &CConfigManager::InitOldDriver                        },
  32.     { "EnableStopStart",                  &CConfigManager::InitEnableStopStart                  },
  33.     { "OldSoundDriver",                   &CConfigManager::InitOldSoundDriver                   },
  34.     { "InvalidDriver",                    &CConfigManager::InitInvalidDriver                    },
  35.     { "InvalidSoundDriver",               &CConfigManager::InitInvalidSoundDriver               },
  36.     { "SafeMode",                         &CConfigManager::InitSafeMode                         },
  37.     { "DisableSpecular",                  &CConfigManager::InitDisableSpecular                  },
  38.     { "UseAnisotropicFilter",             &CConfigManager::InitUseAnisotropicFilter             },
  39.     { "UMA",                              &CConfigManager::InitUMA                              },
  40.     { "DoNotUseMinMaxBlendOp",            &CConfigManager::InitDoNotUseMinMaxBlendOp            },
  41.     { "PrototypeCard",                    &CConfigManager::InitPrototypeCard                    },
  42. };
  43.  
  44.  
  45. static DWORD GetNumber( const char* value )
  46. {
  47.     int result;
  48.     int nRet = sscanf( value, "%d", &result );
  49.     if( nRet == 0 || nRet == EOF )
  50.         result = 0;
  51.     return result;
  52. }
  53.  
  54.  
  55. static float GetFloatNumber( const char* value )
  56. {
  57.     float result;
  58.     int nRet = sscanf( value, "%f", &result );
  59.     if( nRet == 0 || nRet == EOF )
  60.         result = 0.0f;
  61.     return result;
  62. }
  63.  
  64.  
  65. BOOL WINAPI DDEnumCB( GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm )
  66. {
  67.     CConfigManager *pCM = (CConfigManager*)lpContext;
  68.  
  69.     if( pCM->m_nAdapterCount )
  70.     {
  71.         memcpy( &pCM->m_AdapterArray[pCM->m_nAdapterCount].guid, lpGUID, sizeof(GUID) );
  72.     }
  73.     if( strlen( lpDriverName )<31 )
  74.         strcpy( pCM->m_AdapterArray[pCM->m_nAdapterCount].DriverName, lpDriverName );
  75.     else
  76.         pCM->m_AdapterArray[pCM->m_nAdapterCount].DriverName[0] = 0;
  77.  
  78.     pCM->m_nAdapterCount++;
  79.     if( pCM->m_nAdapterCount == 10 )
  80.         return false;
  81.     else
  82.         return true;
  83. }
  84.  
  85.  
  86. CConfigManager::CConfigManager()
  87. {
  88.     InitConfigProperties();
  89.     ZeroMemory( m_AdapterArray, sizeof(m_AdapterArray) );
  90.     m_nAdapterCount = 0;
  91. }
  92.  
  93.  
  94. void CConfigManager::InitConfigProperties()
  95. {
  96.     cf_MaximumResolution = 4096;
  97.     cf_LinearTextureAddressing = 0;
  98.     cf_UseFixedFunction = 0;
  99.     cf_PrototypeCard = 0;
  100.     cf_DisableDriverManagement = 0;
  101.     cf_UseAnisotropicFilter = 0;
  102.     cf_DisableSpecular = 0;
  103.     cf_UnsupportedCard = 0;
  104.     cf_EnableStopStart = 0;
  105.     cf_DisableRenderTargets = 0;
  106.     cf_DisableAlphaRenderTargets = 0;
  107.     cf_OldDriver = 0;
  108.     cf_OldSoundDriver = 0;
  109.     cf_InvalidDriver = 0;
  110.     cf_InvalidSoundDriver = 0;
  111.     cf_SafeMode = 0;
  112.     cf_ForceShader = 0;
  113.     cf_DoNotUseMinMaxBlendOp = 0;
  114. }
  115.  
  116.  
  117. void CConfigManager::InitConfigInformation( D3DCAPS9 &d3dCaps )
  118. {
  119.     //
  120.     // Get system memory size
  121.     //
  122.     MEMORYSTATUS ms;
  123.     GlobalMemoryStatus( &ms );
  124.     SysMemory = (DWORD)(((ms.dwTotalPhys+(16*1024*1024-1)) & ~(16*1024*1024-1) ) >> 20);
  125.  
  126.     //
  127.     // Get CPU speed
  128.     //
  129. #if defined( _WIN64 ) && defined( _IA64_ )
  130.     CpuSpeed = ULONG_MAX;  // On Ia64, skip processor speed detection and just return a large value
  131.                            // so requirement would pass.
  132. #else
  133.     __int64 time,qpc,compare;
  134.  
  135.     HANDLE hThread = GetCurrentThread();
  136.     HANDLE hProcess = GetCurrentProcess();
  137.     long OldPriority = GetThreadPriority(hThread);
  138.     DWORD OldClass = GetPriorityClass(hProcess);
  139.     SetPriorityClass( hProcess,REALTIME_PRIORITY_CLASS );
  140.     SetThreadPriority( hThread,THREAD_PRIORITY_TIME_CRITICAL ); // Run code at realtime priority
  141.     Sleep(100);                                                 // Give windows a chance to run background tasks
  142.  
  143.     QueryPerformanceFrequency((LARGE_INTEGER*)&qpc);
  144.     QueryPerformanceCounter((LARGE_INTEGER*)&compare);
  145.     compare+=qpc/4;                                             // Find time .5 seconds ahead
  146.  
  147. #ifdef _WIN64
  148.     time = __rdtsc();  // Use intrinsic for AMD64 environment
  149. #else
  150.     __asm rdtsc
  151.     __asm mov dword ptr time,eax
  152.     __asm mov dword ptr time+4,edx
  153. #endif
  154.  
  155.     do
  156.     {
  157.         QueryPerformanceCounter((LARGE_INTEGER*)&qpc);          // Spin until time equal
  158.     }
  159.     while( compare>qpc );
  160.  
  161. #ifdef _WIN64
  162.     time = __rdtsc() - time;  // Use intrinsic for AMD64 environment
  163. #else
  164.     __asm rdtsc
  165.     __asm sub eax,dword ptr time
  166.     __asm sbb edx,dword ptr time+4
  167.     __asm mov dword ptr time,eax
  168.     __asm mov dword ptr time+4,edx
  169. #endif
  170.  
  171.     SetThreadPriority(hThread,OldPriority);
  172.     SetPriorityClass(hProcess,OldClass);
  173.  
  174.     //
  175.     // Normalize CPU speed
  176.     //
  177.     CpuSpeed=(DWORD)(time/250000);
  178.  
  179.     if( CpuSpeed>1000 )
  180.     {
  181.         CpuSpeed=((CpuSpeed+50)/100)*100;
  182.     }
  183.  
  184.     DWORD CpuSpeed2=CpuSpeed%100;
  185.  
  186.     if( CpuSpeed<200 )
  187.     {
  188.         if( CpuSpeed2>95 )
  189.         {
  190.             CpuSpeed+=100-CpuSpeed2;
  191.         }
  192.         if( CpuSpeed2>61 && CpuSpeed2<71 )
  193.             CpuSpeed+=66-CpuSpeed2;
  194.         if( CpuSpeed2>45 && CpuSpeed2<55 )
  195.             CpuSpeed+=50-CpuSpeed2;
  196.         if( CpuSpeed2>28 && CpuSpeed2<38 )
  197.             CpuSpeed+=33-CpuSpeed2;
  198.     }
  199.     else
  200.     {
  201.         if( CpuSpeed2>84 )
  202.         {
  203.             CpuSpeed+=100-CpuSpeed2;
  204.         }
  205.         else
  206.         {
  207.             if( CpuSpeed2>58 )
  208.             {
  209.                 CpuSpeed+=66-CpuSpeed2;
  210.             }
  211.             else
  212.             {
  213.                 if( CpuSpeed2>42 )
  214.                 {
  215.                     CpuSpeed+=50-CpuSpeed2;
  216.                 }
  217.                 else
  218.                 {
  219.                     if( CpuSpeed2>16 )
  220.                     {
  221.                         CpuSpeed+=33-CpuSpeed2;
  222.                     }
  223.                     else
  224.                     {
  225.                         if( CpuSpeed2<16 )
  226.                         {
  227.                             CpuSpeed-=CpuSpeed2;
  228.                         }
  229.                     }
  230.                 }
  231.             }
  232.         }
  233.     }
  234. #endif   // _WIN64 && _IA64_
  235.  
  236.     //
  237.     // Get video memory size for all devices using ddraw 7 interfaces
  238.     //
  239.     WCHAR wszPath[MAX_PATH];
  240.     ::GetSystemDirectory( wszPath, MAX_PATH );
  241.     lstrcatW( wszPath, L"\\ddraw.dll" );
  242.     IDirectDraw7* DDobject;
  243.     HINSTANCE ddrawLib = LoadLibraryW( wszPath );
  244.     if( ddrawLib )
  245.     {
  246.         HRESULT (WINAPI* _DirectDrawCreateEx)( GUID* lpGUID, void** lplpDD, REFIID iid, IUnknown* pUnkOuter ) = (HRESULT (WINAPI*)( GUID* lpGUID, void** lplpDD, REFIID iid, IUnknown* pUnkOuter ))GetProcAddress( ddrawLib, "DirectDrawCreateEx" ); 
  247.         if( _DirectDrawCreateEx )
  248.         {
  249.             HRESULT (WINAPI* _DirectDrawEnumerateEx)( LPDDENUMCALLBACKEXA, LPVOID, DWORD ) = (HRESULT (WINAPI*)( LPDDENUMCALLBACKEXA, LPVOID, DWORD )) GetProcAddress( ddrawLib, "DirectDrawEnumerateExA" ); 
  250.             if( _DirectDrawEnumerateEx )
  251.             {
  252.                 //
  253.                 // DirectDraw 7 will enumerate 1 device (NULL). Or a NULL device and then a GUID for each adapter.
  254.                 //
  255.                 _DirectDrawEnumerateEx( DDEnumCB, this, DDENUM_ATTACHEDSECONDARYDEVICES );
  256.  
  257.                 //
  258.                 // Create a DirectDraw object for the device specified
  259.                 //
  260.                 for( int t0 = 0; t0 < m_nAdapterCount; ++t0 )
  261.                 {
  262.                     HRESULT result = _DirectDrawCreateEx( t0 ? &m_AdapterArray[t0].guid : NULL, (void**)&DDobject, IID_IDirectDraw7, NULL );
  263.                     if( SUCCEEDED(result) )
  264.                     {
  265.                         DDobject->SetCooperativeLevel( NULL, DDSCL_NORMAL );
  266.                         //
  267.                         // See how much memory is on the card
  268.                         //
  269.                         DDSCAPS2 ddscaps2;
  270.                         DWORD Junk;
  271.                         DWORD VideoMemory=-1;
  272.                         DWORD Temp=0;
  273.                         memset( &ddscaps2, 0, sizeof(ddscaps2) );
  274.                         ddscaps2.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
  275.                         DDobject->GetAvailableVidMem( &ddscaps2, &Temp, &Junk );
  276.                         if( Temp>0 && Temp<VideoMemory )
  277.                             VideoMemory=Temp;
  278.                         ddscaps2.dwCaps = DDSCAPS_3DDEVICE | DDSCAPS_LOCALVIDMEM | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
  279.                         DDobject->GetAvailableVidMem( &ddscaps2, &Temp, &Junk );
  280.                         if( Temp>0 && Temp<VideoMemory )
  281.                             VideoMemory=Temp;
  282.                         ddscaps2.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
  283.                         DDobject->GetAvailableVidMem( &ddscaps2, &Temp, &Junk );
  284.                         if( Temp>0 && Temp<VideoMemory )
  285.                             VideoMemory=Temp;
  286.                         ddscaps2.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
  287.                         DDobject->GetAvailableVidMem( &ddscaps2, &Temp, &Junk );
  288.                         if( Temp>0 && Temp<VideoMemory )
  289.                             VideoMemory=Temp;
  290.                         //
  291.                         // If cannot get memory size, there must be a problem with D3D / DirectDraw
  292.                         //
  293.                         if( -1==VideoMemory )
  294.                         {
  295.                             VideoMemory = 0;
  296.                         } else
  297.                         {
  298.                             //
  299.                             // Round the video memory number depending upon the size
  300.                             //
  301.                             if( VideoMemory<=16*1024*1024 )
  302.                             {
  303.                                 VideoMemory=((VideoMemory+8*1024*1024-1) & ~(8*1024*1024-1));               // Round up to nearest 8 under 20Meg
  304.                             }
  305.                             else
  306.                             {
  307.                                 if( VideoMemory <= 64*1024*1024 )
  308.                                 {
  309.                                     VideoMemory=((VideoMemory+32*1024*1024-1) & ~(32*1024*1024-1));         // Round to neaest 32 Meg under 64Meg
  310.                                 }
  311.                                 else
  312.                                 {
  313.                                     VideoMemory=((VideoMemory+64*1024*1024-1) & ~(64*1024*1024-1));         // Round to neaest 64 Meg over 64Meg
  314.                                 }
  315.                             }
  316.                         }
  317.  
  318.                         //
  319.                         // Clean up ddraw7
  320.                         //
  321.                         m_AdapterArray[t0].MemorySize = VideoMemory;
  322.                         DDobject->Release();
  323.                     }
  324.                 }
  325.             }
  326.         }
  327.         //
  328.         // Release ddraw7 object
  329.         //
  330.         FreeLibrary( ddrawLib );
  331.     }
  332.  
  333.     //
  334.     // Find the display adapter (ddraw and d3d9 do not enumerate the same order)
  335.     //
  336.     D3DADAPTER_IDENTIFIER9 d3di;
  337.     DXUTGetD3DObject()->GetAdapterIdentifier( d3dCaps.AdapterOrdinal, 0, &d3di );
  338.     DriverVersionLowPart = d3di.DriverVersion.LowPart;
  339.     DriverVersionHighPart = d3di.DriverVersion.HighPart;
  340.     VideoMemory = m_AdapterArray[0].MemorySize;
  341.     for( int i = 0; i < m_nAdapterCount; ++i )
  342.     {
  343.         if( !_stricmp( m_AdapterArray[i].DriverName, d3di.DeviceName ) )
  344.             VideoMemory = m_AdapterArray[i].MemorySize;
  345.     }
  346.  
  347.     //
  348.     // Detect sound configuration
  349.     //
  350.     GUID Guid;
  351.     GetDeviceID( &DSDEVID_DefaultPlayback, &Guid );
  352.     InitSoundInformation( Guid, &Sound_device );
  353. }
  354.  
  355.  
  356. HRESULT CConfigManager::Initialize( WCHAR* FileName, D3DADAPTER_IDENTIFIER9 &AdapterID, D3DCAPS9 &Caps,
  357.                                     REFGUID DSoundDeviceGuid )
  358. {
  359.     HRESULT hr = S_OK;
  360.  
  361.     InitConfigInformation( Caps );
  362.  
  363.     SOUND_DEVICE SndDev;
  364.     InitSoundInformation( DSoundDeviceGuid, &SndDev );
  365.  
  366.     DXUTOutputDebugStringA( "Media device found:\n" );
  367.     DXUTTRACE( L"%s\n", SndDev.name );
  368.  
  369.     IConfigDatabase* pCDB = IConfigDatabase::Create();
  370.     if( pCDB->Load( FileName, SndDev, AdapterID, Caps, 1024, 64, 1700 ) )
  371.     {
  372.         DXUTOutputDebugStringA( "Graphics device string: %s\n", pCDB->GetGfxDeviceString() );
  373.         DXUTOutputDebugStringA( "Graphics vendor string: %s\n", pCDB->GetGfxVendorString() );
  374.         DXUTOutputDebugStringA( "Sound device string: %s\n", pCDB->GetSoundDeviceString() );
  375.         DXUTOutputDebugStringA( "Sound vendor string: %s\n", pCDB->GetSoundVendorString() );
  376.  
  377.         // Interate the properties and initialize the config flags.
  378.         DXUTOutputDebugStringA( "Properties:\n" );
  379.         int nPropCount = pCDB->GetDevicePropertyCount();
  380.         for( int i = 0; i < nPropCount; ++i )
  381.         {
  382.             DXUTOutputDebugStringA( "\"%s\" : \"%s\"\n", pCDB->GetDeviceProperty( i ), pCDB->GetDeviceValue( i ) );
  383.  
  384.             for( int f = 0; f < sizeof(ConfigTable) / sizeof(ConfigTable[0]); ++f )
  385.             {
  386.                 if( !_stricmp( ConfigTable[f].Property, pCDB->GetDeviceProperty( i ) ) )
  387.                 {
  388.                     // Property found. Call the init function.
  389.                     (this->*ConfigTable[f].Func)( pCDB->GetDeviceValue( i ) );
  390.                 }
  391.             }
  392.         }
  393.  
  394.         ::DXUTOutputDebugStringA( "\nRequirements:\n" );
  395.         int nReqCount = pCDB->GetRequirementsPropertyCount();
  396.         for( int i = 0; i < nReqCount; ++i )
  397.         {
  398.             char* Property = (char*)pCDB->GetRequirementsProperty( i );
  399.             char* Value = (char*)pCDB->GetRequirementsValue( i );
  400.             int nRet;
  401.  
  402.             DXUTOutputDebugStringA( "\"%s\" : \"%s\"\n", Property, Value );
  403.  
  404.             if( !_stricmp( "CpuSpeed", Property ) )
  405.             {
  406.                 nRet = sscanf( Value, "%d",&req_CPUSpeed );
  407.                 if( nRet == 0 || nRet == EOF )
  408.                     req_CPUSpeed = 0;
  409.             } else
  410.             if( !_stricmp( "Memory", Property ) )
  411.             {
  412.                 nRet = sscanf( Value, "%d",&req_Memory );
  413.                 if( nRet == 0 || nRet == EOF )
  414.                     req_Memory = 0;
  415.             } else
  416.             if( !_stricmp( "VideoMemory", Property ) )
  417.             {
  418.                 nRet = sscanf( Value, "%d",&req_VideoMemory );
  419.                 if( nRet == 0 || nRet == EOF )
  420.                     req_VideoMemory = 0;
  421.             } else
  422.             if( !_stricmp( "DirectX", Property ) )
  423.             {
  424.                 nRet = sscanf( Value, "%d.%d%c", &req_DirectXMajor, &req_DirectXMinor, &req_DirectXLetter );
  425.                 req_DirectXLetter = (char)req_DirectXLetter;  // Convert to wide char
  426.                 if( nRet == 0 || nRet == EOF )
  427.                 {
  428.                     req_DirectXMajor = req_DirectXMinor = 0;
  429.                     req_DirectXLetter = L' ';
  430.                 }
  431.             } else
  432.             if( !_stricmp( "DiskSpace", Property ) )
  433.             {
  434.                 nRet = sscanf( Value, "%d",&req_DiskSpace );
  435.                 if( nRet == 0 || nRet == EOF )
  436.                     req_DiskSpace = 0;
  437.             } else
  438.             if( !_stricmp( "OS", Property ) )
  439.             {
  440.                 if( !_stricmp( "Win95", Value ) )
  441.                 {
  442.                     req_OSMajor = 4;
  443.                     req_OSMinor = 0;
  444.                 } else
  445.                 if( !_stricmp( "Win98", Value ) )
  446.                 {
  447.                     req_OSMajor = 4;
  448.                     req_OSMinor = 10;
  449.                 } else
  450.                 if( !_stricmp( "WinME", Value ) )
  451.                 {
  452.                     req_OSMajor = 4;
  453.                     req_OSMinor = 90;
  454.                 } else
  455.                 if( !_stricmp( "Win2k", Value ) )
  456.                 {
  457.                     req_OSMajor = 5;
  458.                     req_OSMinor = 0;
  459.                 } else
  460.                 if( !_stricmp( "WinXP", Value ) )
  461.                 {
  462.                     req_OSMajor = 5;
  463.                     req_OSMinor = 1;
  464.                 } else
  465.                 if( !_stricmp( "Win2003", Value ) )
  466.                 {
  467.                     req_OSMajor = 5;
  468.                     req_OSMinor = 2;
  469.                 }
  470.             }
  471.         }
  472.     }
  473.     else
  474.     {
  475.         hr = E_FAIL;
  476.     }
  477.  
  478.     pCDB->Release();
  479.  
  480.     return hr;
  481. }
  482.  
  483.  
  484. bool CConfigManager::InitMaximumResolution( const char* value )
  485. {
  486.     DWORD val = GetNumber( value );
  487.     if( val < 640 || val > 4096 )
  488.     {
  489.         return false;
  490.     }
  491.     cf_MaximumResolution=val;
  492.     return true;
  493. }
  494.  
  495.  
  496. bool CConfigManager::InitForceShader( const char* value )
  497. {
  498.     if( *(WORD*)value=='a2' || *(WORD*)value=='A2' )
  499.     {
  500.         cf_ForceShader=9998;
  501.     }
  502.     else
  503.     if( *(WORD*)value=='b2' || *(WORD*)value=='B2' )
  504.     {
  505.         cf_ForceShader=9997;
  506.     }
  507.     else
  508.     {
  509.         cf_ForceShader = GetNumber( value );
  510.         if( 0==cf_ForceShader )
  511.             cf_ForceShader=9999;
  512.     }
  513.     return true;
  514. }
  515.  
  516.  
  517. bool CConfigManager::InitLinearTextureAddressing( const char* value )
  518. {
  519.     cf_LinearTextureAddressing=1;
  520.     return true;
  521. }
  522.  
  523.  
  524. bool CConfigManager::InitUseAnisotropicFilter( const char* value )
  525. {
  526.     cf_UseAnisotropicFilter=1;
  527.     return true;
  528. }
  529.  
  530.  
  531. bool CConfigManager::InitDisableSpecular( const char* value )
  532. {
  533.     cf_DisableSpecular=1;
  534.     return true;
  535. }
  536.  
  537.  
  538. bool CConfigManager::InitUseFixedFunction( const char* value )
  539. {
  540.     cf_UseFixedFunction=1;
  541.     return true;
  542. }
  543.  
  544.  
  545.  
  546. bool CConfigManager::InitDisableRenderTargets( const char* value )
  547. {
  548.     cf_DisableRenderTargets=1;
  549.     return true;
  550. }
  551.  
  552.  
  553. bool CConfigManager::InitDisableAlphaRenderTargets( const char* value )
  554. {
  555.     cf_DisableAlphaRenderTargets=1;
  556.     return true;
  557. }
  558.  
  559.  
  560. bool CConfigManager::InitPrototypeCard( const char* value )
  561. {
  562.     cf_PrototypeCard=1;
  563.     return true;
  564. }
  565.  
  566.  
  567. bool CConfigManager::InitUnsupportedCard( const char* value )
  568. {
  569.     cf_UnsupportedCard=1;
  570.     return true;
  571. }
  572.  
  573.  
  574. bool CConfigManager::InitOldDriver( const char* value )
  575. {
  576.     cf_OldDriver=1;
  577.     return true;
  578. }
  579.  
  580.  
  581. bool CConfigManager::InitEnableStopStart( const char* value )
  582. {
  583.     cf_EnableStopStart=1;
  584.     return true;
  585. }
  586.  
  587.  
  588. bool CConfigManager::InitOldSoundDriver( const char* value )
  589. {
  590.     cf_OldSoundDriver=1;
  591.     return true;
  592. }
  593.  
  594.  
  595. bool CConfigManager::InitInvalidDriver( const char* value )
  596. {
  597.     cf_InvalidDriver=1;
  598.     return true;
  599. }
  600.  
  601.  
  602. bool CConfigManager::InitInvalidSoundDriver( const char* value )
  603. {
  604.     cf_InvalidSoundDriver=1;
  605.     return true;
  606. }
  607.  
  608.  
  609. bool CConfigManager::InitSafeMode( const char* value )
  610. {
  611.     cf_SafeMode=1;
  612.     return true;
  613. }
  614.  
  615.  
  616. bool CConfigManager::InitDisableDriverManagement( const char* value )
  617. {
  618.     cf_DisableDriverManagement=1;
  619.     return true;
  620. }
  621.  
  622.  
  623. //
  624. //   0-64Meg  = 8Meg video memory
  625. //  64-128Meg = 16Meg video memory
  626. // 128-256    = 32Meg video memory
  627. // 256+       = 64Meg video memory
  628. //
  629. bool CConfigManager::InitUMA( const char* value )
  630. {
  631.     VideoMemory = 8*1024*1024;
  632.     if( SysMemory >= 64 )
  633.         VideoMemory = 16*1024*1024;
  634.     if( SysMemory >= 128 )
  635.         VideoMemory = 32*1024*1024;
  636.     if( SysMemory >= 256 )
  637.         VideoMemory = 64*1024*1024;
  638.     return true;
  639. }
  640.  
  641.  
  642. bool CConfigManager::InitDoNotUseMinMaxBlendOp( const char* value )
  643. {
  644.     cf_DoNotUseMinMaxBlendOp = 1;
  645.     return true;
  646. }
  647.  
  648.  
  649. HRESULT CConfigManager::VerifyRequirements()
  650. {
  651.     HRESULT hr = S_OK;
  652.     WCHAR wszText[2048] = L"This system does not meet the following minimum requirement(s):\n\n";
  653.  
  654.     //
  655.     // OS version
  656.     //
  657.     OSVERSIONINFO ovi;
  658.     ovi.dwOSVersionInfoSize = sizeof(ovi);
  659.     GetVersionEx( &ovi );
  660.     if( req_OSMajor > ovi.dwMajorVersion ||
  661.         ( req_OSMajor == ovi.dwMajorVersion && req_OSMinor > ovi.dwMinorVersion ) )
  662.     {
  663.         // OS version not supported.
  664.         hr = E_FAIL;
  665.         wcsncat( wszText, L"- Operating system not supported\n", 2048 - lstrlenW( wszText ) );
  666.         wszText[2047] = L'\0';
  667.     }
  668.  
  669.     //
  670.     // CPU speed
  671.     //
  672.     if( CpuSpeed < req_CPUSpeed )
  673.     {
  674.         hr = E_FAIL;
  675.         WCHAR wsz[256];
  676.         swprintf( wsz, L"- Minimum processor speed of %u MHz\n", req_CPUSpeed );
  677.         wcsncat( wszText, wsz, 2048 - lstrlenW( wszText ) );
  678.         wszText[2047] = L'\0';
  679.     }
  680.  
  681.     //
  682.     // Memory size
  683.     //
  684.     if( SysMemory < req_Memory )
  685.     {
  686.         hr = E_FAIL;
  687.         WCHAR wsz[256];
  688.         swprintf( wsz, L"- Minimum memory of %u megabytes\n", req_Memory );
  689.         wcsncat( wszText, wsz, 2048 - lstrlenW( wszText ) );
  690.         wszText[2047] = L'\0';
  691.     }
  692.  
  693.     //
  694.     // Video memory size
  695.     //
  696.     if( (VideoMemory >> 20) < req_VideoMemory )
  697.     {
  698.         hr = E_FAIL;
  699.         WCHAR wsz[256];
  700.         swprintf( wsz, L"- Minimum video memory of %u megabytes\n", req_VideoMemory );
  701.         wcsncat( wszText, wsz, 2048 - lstrlenW( wszText ) );
  702.         wszText[2047] = L'\0';
  703.     }
  704.  
  705.     //
  706.     // DirectX version
  707.     //
  708.     DWORD dwDXMajor = 0;
  709.     DWORD dwDXMinor = 0;
  710.     TCHAR cDXLetter = ' ';
  711.     GetDXVersion( &dwDXMajor, &dwDXMinor, &cDXLetter );
  712.  
  713.     if( dwDXMajor < req_DirectXMajor ||
  714.         ( dwDXMajor == req_DirectXMajor && dwDXMinor < req_DirectXMinor ) ||
  715.         ( dwDXMajor == req_DirectXMajor && dwDXMinor == req_DirectXMinor && cDXLetter < req_DirectXLetter ) )
  716.     {
  717.         hr = E_FAIL;
  718.         WCHAR wsz[256];
  719.         swprintf( wsz, L"- DirectX %u.%u%c\n", req_DirectXMajor, req_DirectXMinor, req_DirectXLetter );
  720.         wcsncat( wszText, wsz, 2048 - lstrlenW( wszText ) );
  721.         wszText[2047] = L'\0';
  722.     }
  723.  
  724.     if( FAILED( hr ) )
  725.     {
  726.         ::MessageBox( NULL, wszText, L"Minimum Requirement", MB_OK|MB_ICONERROR );
  727.     }
  728.  
  729.     return hr;
  730. }
  731.